package com.sikadwafastdaisfondturbo.pretloan.utils.http

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import com.sikadwafastdaisfondturbo.pretloan.R
import com.sikadwafastdaisfondturbo.pretloan.base.BaseActivity
import com.sikadwafastdaisfondturbo.pretloan.utils.config.Configs
import com.sikadwafastdaisfondturbo.pretloan.utils.dialog.RequestErrorDialog
import com.sikadwafastdaisfondturbo.pretloan.utils.dialog.RequestErrorDialog.IDialogCallback
import com.sikadwafastdaisfondturbo.pretloan.utils.helper.ToastHelper
import com.sikadwafastdaisfondturbo.pretloan.utils.log.HHLog
import org.greenrobot.eventbus.EventBus
import org.json.JSONObject
import java.io.File
import java.lang.ref.WeakReference

/**
 * 全局网络错误管理器
 */
@SuppressLint("StaticFieldLeak")
object GlobalNetworkManager {
    // 应用上下文
    private var context: Context? = null

    // 待重试请求队列
    private val pendingRequests = mutableListOf<RetryRequest>()
    // 主线程 Handler 复用
    private val mainHandler = Handler(Looper.getMainLooper())

    // 对话框显示状态
    private var isShowingDialog = false

    // 重试对话框实例
    private var retryDialog: RequestErrorDialog? = null

    // 当前活动的Activity（弱引用避免内存泄漏）
    private var currentActivity: WeakReference<BaseActivity>? = null

    // 同步锁，确保线程安全
    private val lock = Any()

    // 对话框显示次数统计
    private var showCount = 0

    /**
     * 重试请求数据类
     * @param url 请求URL
     * @param method 请求方法（GET/POST）
     * @param params 请求参数
     * @param callback 请求回调
     * @param isFileUpload 是否为文件上传请求
     * @param file 上传的文件
     * @param retryCount 已重试次数
     */
    data class RetryRequest(
        val url: String,
        val method: String,
        val params: JSONObject? = null,
        val callback: IHttpCallback,
        val isFileUpload: Boolean = false,
        val file: File? = null,
        val retryCount: Int = 0
    )

    /**
     * 初始化方法
     * @param appContext 应用上下文
     */
    fun initialize(appContext: Context) {
        context = appContext.applicationContext
        registerActivityLifecycleCallbacks()
    }

    /**
     * 注册Activity生命周期回调
     */
    private fun registerActivityLifecycleCallbacks() {
        val appContext = context
        if (appContext is Application) {
            appContext.registerActivityLifecycleCallbacks(
                object : ActivityLifecycleCallbacksAdapter() {
                    override fun onActivityDestroyed(activity: Activity) {
                        // Activity销毁时自动注销
                        if (activity is BaseActivity) {
                            unregisterActivity(activity)
                        }
                    }
                }
            )
        }
    }

    /**
     * 注册当前Activity
     * @param activity 当前Activity实例
     */
    fun registerActivity(activity: BaseActivity) {
        currentActivity = WeakReference(activity)
        showCount = 0
        HHLog.d("GlobalNetworkManager: registerActivity - ${activity.javaClass.simpleName}")
    }

    /**
     * 注销Activity
     * @param activity 要注销的Activity实例
     */
    fun unregisterActivity(activity: BaseActivity) {
        if (currentActivity?.get() == activity) {
            currentActivity = null
            dismissDialog()
            HHLog.d("GlobalNetworkManager: unregisterActivity - ${activity.javaClass.simpleName}")
        }
    }

    /**
     * 获取当前有效的Activity
     * @return 当前有效的BaseActivity实例，如果不存在或已销毁则返回null
     */
    private fun getCurrentActivity(): BaseActivity? {
        return currentActivity?.get()?.takeIf {
            !it.isFinishing && !it.isDestroyed
        }
    }

    /**
     * 处理网络错误
     * @param errorCode 错误码
     * @param errorMsg 错误信息
     * @param request 失败的请求
     */
    fun handleNetworkError(errorCode: Int, errorMsg: String?, request: RetryRequest) {
        HHLog.i("GlobalNetworkManager: handleNetworkError - code=$errorCode, url=${request.url}")
        // 使用同步锁确保线程安全
        synchronized(lock) {
            if (isGlobalError(errorCode)) {
                // 全局错误：添加到重试队列并显示对话框
                addRequestToPendingQueue(request)
                showDialogIfNeeded()
            } else {
                // 局部错误：直接回调错误信息
                handleLocalError(errorCode, errorMsg, request)
            }
        }
    }

    /**
     * 判断是否为全局错误
     * @param errorCode 错误码
     * @return true-全局错误，false-局部错误
     */
    private fun isGlobalError(errorCode: Int): Boolean {
        // -1: 网络不可用，408: 请求超时，500-599: 服务器错误
        return errorCode == -1 || errorCode == 408 || errorCode in 500..599
    }

    /**
     * 添加请求到待重试队列（去重）
     * @param request 要添加的请求
     */
    private fun addRequestToPendingQueue(request: RetryRequest) {
        val isDuplicate = pendingRequests.any { existingRequest ->
            isDuplicateRequest(request, existingRequest)
        }

        if (!isDuplicate) {
            pendingRequests.add(request)
            HHLog.d("GlobalNetworkManager: Add to retry queue - ${request.url}, Queue size: ${pendingRequests.size}")
        } else {
            HHLog.d("GlobalNetworkManager: Skip duplicate requests - ${request.url}")
        }
    }

    /**
     * 判断是否为重复请求
     * @param newRequest 新请求
     * @param existingRequest 已存在的请求
     * @return true-重复请求，false-非重复请求
     */
    private fun isDuplicateRequest(newRequest: RetryRequest, existingRequest: RetryRequest): Boolean {
        return when {
            newRequest.method == "GET" -> newRequest.url == existingRequest.url
            newRequest.method == "POST" -> {
                newRequest.url == existingRequest.url && newRequest.params?.optString("path") == existingRequest.params?.optString("path")
            }
            else -> newRequest.url == existingRequest.url && newRequest.method == existingRequest.method
        }
    }

    /**
     * 处理局部错误
     * @param errorCode 错误码
     * @param errorMsg 错误信息
     * @param request 请求实例
     */
    private fun handleLocalError(errorCode: Int, errorMsg: String?, request: RetryRequest) {
        val errorObj = createErrorJSON(errorCode, errorMsg)
        mainHandler.post {
            request.callback.onRequestError(errorObj)
            // 确保调用完成回调
            request.callback.onRequestFinish()
        }
        showToast(getErrorMessage(errorCode, errorMsg))
    }

    /**
     * 如果需要则显示重试对话框
     */
    private fun showDialogIfNeeded() {
        // 如果对话框已经在显示，则不需要再次显示
        if (!isShowingDialog) {
            isShowingDialog = true
            showGlobalRetryDialog()
        }
    }

    /**
     * 显示全局重试对话框
     */
    private fun showGlobalRetryDialog() {
        mainHandler.post {
            val activity = getCurrentActivity() ?: run {
                // 没有有效的Activity，重置状态
                synchronized(lock) { isShowingDialog = false }
                HHLog.w("GlobalNetworkManager: No valid activity displaying retry dialog box")
                return@post
            }

            // 检查对话框是否已经在显示
            if (retryDialog?.isShowing == true) {
                HHLog.d("GlobalNetworkManager: The dialog box is already displayed")
                return@post
            }

            try {
                // 根据显示次数选择错误信息
                val errorMsg = if (showCount > 2) {
                    activity.getString(R.string.tips_load_network_failed)
                } else {
                    activity.getString(R.string.tips_load_failed)
                }

                // 通知请求失败事件
                EventBus.getDefault().post(Configs.Event.REQUEST_FINISH_FAILED)
                showCount++

                // 创建并显示重试对话框
                createAndShowRetryDialog(activity, errorMsg)

            } catch (e: Exception) {
                HHLog.e("GlobalNetworkManager: Display dialog box failed - ${e.message}")
                synchronized(lock) { isShowingDialog = false }
                retryDialog = null
            }
        }
    }

    /**
     * 创建并显示重试对话框
     * @param activity 当前Activity
     * @param errorMsg 错误信息
     */
    private fun createAndShowRetryDialog(activity: BaseActivity, errorMsg: String) {
        retryDialog = RequestErrorDialog(activity, activity.javaClass.name,
            object : IDialogCallback {
                override fun onReloadClick() {
                    HHLog.i("GlobalNetworkManager: The user clicks retry to retry ${pendingRequests.size} requests")
                    activity.showLoading()
                    retryAllPendingRequests()
                }
            })

        // 设置对话框关闭监听器
        retryDialog?.setOnDismissListener {
            synchronized(lock) {
                isShowingDialog = false
                retryDialog = null
            }
        }

        // 设置对话框不可取消
        retryDialog?.setCancelable(false)
        retryDialog?.setCanceledOnTouchOutside(false)

        // 最终检查Activity状态后显示对话框
        if (!activity.isFinishing && !activity.isDestroyed) {
            retryDialog?.show()
            retryDialog?.setTips(errorMsg)
            HHLog.i("GlobalNetworkManager: Display retry dialog box - $errorMsg")
        } else {
            synchronized(lock) {
                isShowingDialog = false
                retryDialog = null
            }
            HHLog.w("GlobalNetworkManager: Activity status is invalid, dialog box is not displayed")
        }
    }

    /**
     * 关闭对话框
     */
    private fun dismissDialog() {
        mainHandler.post {
            try {
                retryDialog?.dismiss()
            } catch (e: Exception) {
                HHLog.e("GlobalNetworkManager: Failed to close dialog box - ${e.message}")
            } finally {
                synchronized(lock) {
                    isShowingDialog = false
                    retryDialog = null
                }
            }
        }
    }

    /**
     * 重试所有待处理请求
     */
    private fun retryAllPendingRequests() {
        val requestsToRetry = synchronized(lock) {
            pendingRequests.toList().also {
                pendingRequests.clear()
                HHLog.i("GlobalNetworkManager: Starting to retry ${it.size} requests")
            }
        }

        // 错开重试时间，避免同时发起大量请求
        requestsToRetry.forEachIndexed { index, request ->
            mainHandler.postDelayed({
                executeRetryRequest(request)
            }, index * 500L) // 每个请求间隔500ms
        }
    }

    /**
     * 执行单个请求的重试
     * @param request 要重试的请求
     */
    private fun executeRetryRequest(request: RetryRequest) {
        HHLog.i("GlobalNetworkManager: Retry request - ${request.url}, retryCount: ${request.retryCount}")

        // 创建新的请求实例，增加重试次数
        val newRequest = request.copy(retryCount = request.retryCount + 1)
        try {
            when {
                newRequest.isFileUpload && newRequest.file != null -> {
                    // 文件上传请求
                    HttpHelper.uploadFile(newRequest.url, newRequest.file, newRequest.callback)
                }
                newRequest.method == "GET" -> {
                    // GET请求
                    HttpHelper.get(newRequest.url, newRequest.callback)
                }
                else -> {
                    HttpHelper.post(newRequest.url, newRequest.params ?: JSONObject(), newRequest.callback)
                    // POST请求（特殊处理埋点请求）
                    if (newRequest.params?.optString("path") == AppUrls.PATH.TRACK_EVENT_BATCH) {
                        mainHandler.postDelayed({
                            EventBus.getDefault().post(Configs.Event.REQUEST_FINISH_FAILED)
                        },3000)
                    }
                }
            }
        } catch (e: Exception) {
            HHLog.e("GlobalNetworkManager: Failed to retry request execution - ${e.message}")
        }
    }

    /**
     * 创建错误JSON对象
     * @param code 错误码
     * @param msg 错误信息
     * @return JSONObject错误对象
     */
    private fun createErrorJSON(code: Int, msg: String?): JSONObject {
        return JSONObject().apply {
            put("errorCode", code)
            put("errorMsg", msg ?: "Unknown error")
        }
    }

    /**
     * 获取用户友好的错误信息
     * @param errorCode 错误码
     * @param errorMsg 原始错误信息
     * @return 用户友好的错误信息
     */
    private fun getErrorMessage(errorCode: Int, errorMsg: String?): String {
        return when {
            errorCode == -1 -> context?.getString(R.string.tips_load_network_failed) ?: "Network connection failure"
            errorCode == 408 -> context?.getString(R.string.tips_load_failed) ?: "Request timeout"
            errorCode in 500..599 -> context?.getString(R.string.tips_load_failed) ?: "Server Error"
            else -> errorMsg ?: context?.getString(R.string.tips_load_network_failed) ?: "Network error"
        }
    }

    /**
     * 显示Toast提示
     * @param message 要显示的消息
     */
    private fun showToast(message: String) {
        context?.let {
            mainHandler.post {
                try {
                    ToastHelper.showShortText(it, message)
                } catch (e: Exception) {
                    HHLog.e("GlobalNetworkManager: Display Toast failed - ${e.message}")
                }
            }
        }
    }
}

/**
 * Activity生命周期回调适配器
 * 简化Activity生命周期回调的实现
 */
abstract class ActivityLifecycleCallbacksAdapter : Application.ActivityLifecycleCallbacks {
    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
    override fun onActivityStarted(activity: Activity) {}
    override fun onActivityResumed(activity: Activity) {}
    override fun onActivityPaused(activity: Activity) {}
    override fun onActivityStopped(activity: Activity) {}
    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
    override fun onActivityDestroyed(activity: Activity) {}
}